package splitcity.geom;



import processing.core.PGraphics;
import processing.core.PVector;


public class Rect {
	public float x1=Float.POSITIVE_INFINITY;
	public float y1=Float.POSITIVE_INFINITY;
	public float x2=Float.NEGATIVE_INFINITY;
	public float y2=Float.NEGATIVE_INFINITY;
	public Rect(float x1,float y1,float x2,float y2){
		this.x1=x1;
		this.x2=x2;
		this.y1=y1;
		this.y2=y2;
		
	}
	public Rect(){
	}
	public Rect(Rect r){
		setRect(r);
	}
	public void setRect(Rect r){
		this.x1=r.x1;
		this.x2=r.x2;
		this.y1=r.y1;
		this.y2=r.y2;
	}
	
	
	public void addPos2D(PVector p){
		addPos2D((float)p.x,(float)p.y);
	}
	public void addPos2D(float x,float y){
		if (x<x1)x1=x;
		if (y<y1)y1=y;
		if (x>x2)x2=x;
		if (y>y2)y2=y;
	}
	public float getDimX(){
		return x2-x1;
	}
	public float getDimY(){
		return y2-y1;
	}
	public float getDiagonal(){
		float dX=getDimX();
		float dY=getDimY();
		return (float)Math.sqrt(dX*dX+dY*dY);
	}
	public float getArea(){
		return getDimX()*getDimY();
	}
	public boolean contains(float x,float y){
		if (x<x2&&x>=x1&&y<y2&&y>=y1)return true;
		return false;
	}
	
	
	public float getCenterX(){
		return (x1+x2)*0.5f;
	}
	public float getCenterY(){
		return (y1+y2)*0.5f;
	}

	public float getOverlap(double a1,double a2,double b1,double b2){
		double v1=Math.max(a1, b1);
		double v2=Math.min(a2, b2);
		if (v2<v1)return 0;
		return (float)(v2-v1);
	}
	public float getOverlapX(Rect r){
		return getOverlap(r.getX1(),r.getX2(),getX1(),getX2());
	}
	public float getOverlapY(Rect r){
		return getOverlap(r.getY1(),r.getY2(),getY1(),getY2());
	}
	public float getOverlapArea(Rect r){
		return getOverlapY(r)*getOverlapX(r);
	}
	public boolean intersects(Rect r2D){
		float ov1=getOverlap(x1,x2,r2D.x1,r2D.x2);
		float ov2=getOverlap(y1,y2,r2D.y1,r2D.y2);
		if (ov1>=0&&ov2>=0)return true;
		return false;
	}
	public float getDistance(float x,float y){
		if (contains(x,y))return 0;
		if (x>=x1&&x<=x2){
			if (y<=y1)return Math.abs(y-y1);
			if (y>=y2)return Math.abs(y-y2);
		}
		if (y>=y1&&y<=y2){
			if (x<=x1)return Math.abs(x-x1);
			if (x>=x2)return Math.abs(x-x2);
		}
		
		if (y<y1){
			if (x<x1)return AbstractGeom.distance(x1, y1, x, y);
			else return AbstractGeom.distance(x2, y1, x, y);
		}
		else{
			if (x<x1)return AbstractGeom.distance(x1, y2, x, y);
			else return AbstractGeom.distance(x2, y2, x, y);
		}
		
	}
	public float getMaxDimension(){
		return Math.max(getDimX(), getDimY());
	}
	public float getMinDimension(){
		return Math.min(getDimX(), getDimY());
	}
	public float getX1() {
		return x1;
	}
	public void setX1(float x1) {
		this.x1 = x1;
	}
	public float getX2() {
		return x2;
	}
	public void setX2(float x2) {
		this.x2 = x2;
	}
	public float getY1() {
		return y1;
	}
	public void setY1(float y1) {
		this.y1 = y1;
	}
	public float getY2() {
		return y2;
	}
	public void setY2(float y2) {
		this.y2 = y2;
	}
	@Override
	public String toString() {
		// TODO Auto-generated method stub
		
		return super.toString()+" x1: "+x1+" y1: "+y1+" w: "+getDimX()+" h: "+getDimY();
	}

	public void addRect2D(Rect b){
		x1=Math.min(x1,b.getX1());
		y1=Math.min(y1,b.getY1());
		x2=Math.max(x2,b.getX2());
		y2=Math.max(y2,b.getY2());
	}
	
	public Rect getOffset(float offset){
		return new Rect(getX1()+offset,getY1()+offset,getX2()-offset,getY2()-offset);
	}
	public void display(PGraphics g){
		g.rect(getX1(),getY1(),getDimX(),getDimY());
	}
}
